/* vim:set noet ts=4: */
/** 
 * scim-python
 * 
 * Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 * $Id: $
 */

#include "scim-python.h"

using namespace scim;

struct PyIMEngineFactoryObject{
	PyListObject list;
	/* Type-specific fields go here. */
	PyIMEngineFactory *factory;
};

PyIMEngineFactory::PyIMEngineFactory (PyObject *self, PyObject *config)
	:self (self), config (config)
{
	Py_INCREF (self);
	Py_INCREF (config);
	
	reload_signal_connection = 
		PyConfig_from_pyobject (config)->signal_connect_reload (slot (this, &PyIMEngineFactory::reload_config));

};

PyIMEngineFactory::~PyIMEngineFactory () 
{
	reload_signal_connection.disconnect ();
	Py_XDECREF (config);
	Py_XDECREF (self);
}

String 
PyIMEngineFactory::get_attr_string (char *name) const
{
	PyObject *pValue;
	String result;
	
	pValue = PyObject_GetAttrString (self, name);
	
	if (pValue) {
		char *str = PyString_AsString (pValue);
		result = String (str);
		Py_DECREF (pValue);
	}
	else {
		PyErr_Print ();
	}
	return result;
}

WideString
PyIMEngineFactory::get_attr_unicode (char *name) const
{
	PyObject *pValue;
	WideString result;
	
	pValue = PyObject_GetAttrString (self, name);
	
	if (pValue) {
		Py_UNICODE *str = PyUnicode_AS_UNICODE (pValue);
		result = WideString ((wchar_t *)str);
		Py_DECREF (pValue);
	}
	else {
		PyErr_Print ();
	}	
	return result;
}
	
WideString
PyIMEngineFactory::get_name () const 
{
	return get_attr_unicode ("name");
}

String
PyIMEngineFactory::get_uuid () const 
{ 
	return get_attr_string ("uuid");
}

String
PyIMEngineFactory::get_icon_file () const 
{
	return get_attr_string ("icon_file");
}

WideString
PyIMEngineFactory::get_authors () const 
{
	return get_attr_unicode ("authors");
}

WideString
PyIMEngineFactory::get_credits () const 
{
	return get_attr_unicode ("get_credits");
}

WideString
PyIMEngineFactory::get_help () const 
{
	return get_attr_unicode ("help");
}

bool 
PyIMEngineFactory::validate_encoding (const String& encoding)
{ 
	return true; 
}

bool
PyIMEngineFactory::validate_locale (const String& locale)
{
	return true; 
}


PyObject *
PyIMEngineFactory::py_set_languages (PyIMEngineFactoryObject *self, PyObject *args)
{
	char * languages;
	PyIMEngineFactory *factory;	
	factory = (PyIMEngineFactory *)(IMEngineFactoryBase *)((PyIMEngineFactoryObject *)self)->factory;

	if (!PyArg_ParseTuple(args, "s:set_language", &languages))
			return NULL;
	
	factory->set_languages (languages);

	Py_INCREF(Py_None);
	return Py_None;	
}

IMEngineInstancePointer
PyIMEngineFactory::create_instance (const String& encoding, int id) 
{
	PyObject *pFunc, *pValue, *pArgs;
	IMEngineInstancePointer result(0);
	
	pFunc = PyObject_GetAttrString (self, "create_instance");
	
	if (pFunc) {
		pArgs = PyTuple_New (2);
		PyTuple_SET_ITEM (pArgs, 0, PyString_FromString(encoding.c_str()));
		PyTuple_SET_ITEM (pArgs, 1, PyInt_FromLong(id));
		pValue = PyObject_CallObject(pFunc, pArgs);
		if (pValue == NULL) {
			PyErr_Print ();
		}
		result = PyIMEngine::from_pyobject (pValue);
		Py_DECREF (pArgs);
		Py_DECREF (pFunc);
	}
	else {
		PyErr_Print ();
	}
	
	return result;
}


void 
PyIMEngineFactory::reload_config (const ConfigPointer &config)
{
    PyObject *pFunc = NULL;
	PyObject *pValue = NULL;
	PyObject *pArgs = NULL;

	pFunc = PyObject_GetAttrString(this->self, "reload_config");
    if (pFunc == NULL)
    	goto _failed_out;

	pArgs = Py_BuildValue ("(O)", this->config);
	if (pArgs == NULL)
		goto _failed_out;

	pValue = PyObject_CallObject (pFunc, pArgs);
	if (pValue == NULL)
    	goto _failed_out;

	Py_DECREF (pArgs);
	Py_DECREF (pFunc);
	Py_DECREF (pValue);
	
	return;

_failed_out:
	PyErr_Print ();
	Py_XDECREF (pArgs);
	Py_XDECREF (pFunc);
	Py_XDECREF (pValue);
}

PyMethodDef 
PyIMEngineFactory::py_methods[] = { 
		{	"set_languages", (PyCFunction)PyIMEngineFactory::py_set_languages, METH_VARARGS,
			"Set languages"
		},
		{ NULL }
};

PyObject *
PyIMEngineFactory::py_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyIMEngineFactory *self;

	self = (PyIMEngineFactory *)type->tp_alloc(type, 0);
	return (PyObject *)self;
}

int
PyIMEngineFactory::py_init (PyIMEngineFactoryObject *self, PyObject *args, PyObject *kwds)
{
	PyObject *config;

	if (!PyArg_ParseTuple(args, "O:__init__", &config))
			return -1;
	self->factory = new PyIMEngineFactory ((PyObject *)self, config);

	return 0;
}

void
PyIMEngineFactory::py_dealloc (PyIMEngineFactoryObject *self)
{
	PyIMEngineFactory *factory = (PyIMEngineFactory *)(IMEngineFactoryBase *)self->factory;
	Py_XDECREF (factory->config);
	factory->config = NULL;
	self->factory = NULL;
}


IMEngineFactoryBase *
PyIMEngineFactory::from_pyobject(PyObject *object)
{
	PyIMEngineFactoryObject *self = (PyIMEngineFactoryObject *) object;
	return (IMEngineFactoryBase *)self->factory;
}

PyTypeObject PyIMEngineFactoryType = {
	PyObject_HEAD_INIT(NULL)
	0,						 							/*ob_size*/
	"scim.IMEngineFactory", 							/*tp_name*/
	sizeof(PyIMEngineFactoryObject),					/*tp_basicsize*/
	0,						 							/*tp_itemsize*/
	0, //(destructor)PyIMEngineFactory::py_dealloc,			/*tp_dealloc*/
	0,			  										/*tp_print*/
	0,						 							/*tp_getattr*/
	0,													/*tp_setattr*/
	0,													/*tp_compare*/
	0,									/*tp_repr*/
	0,									/*tp_as_number*/
	0,									/*tp_as_sequence*/
	0,									/*tp_as_mapping*/
	0,									/*tp_hash */
	0,									/*tp_call*/
	0,		  							/*tp_str*/
	0,					   				/*tp_getattro*/
	0,									/*tp_setattro*/
	0,					 				/*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT | 
	Py_TPFLAGS_BASETYPE,				/*tp_flags*/
	"IMEngineInstanceBase objects",		/* tp_doc */
	0,					   /* tp_traverse */
	0,					   /* tp_clear */
	0,					   /* tp_richcompare */
	0,					   /* tp_weaklistoffset */
	0,					   /* tp_iter */
	0,					   /* tp_iternext */
	PyIMEngineFactory::py_methods,			 /* tp_methods */
	0,			 /* tp_members */
	0,						 /* tp_getset */
	0,						 /* tp_base */
	0,						 /* tp_dict */
	0,						 /* tp_descr_get */
	0,						 /* tp_descr_set */
	0,						 /* tp_dictoffset */
	(initproc)PyIMEngineFactory::py_init,	  /* tp_init */
	0,						 /* tp_alloc */
	PyIMEngineFactory::py_new,				 /* tp_new */	
};

void init_factory (PyObject *module)
{
	if (PyType_Ready(&PyIMEngineFactoryType) < 0)
		return;

	Py_INCREF(&PyIMEngineFactoryType);
	PyModule_AddObject(module, "IMEngineFactory", (PyObject *)&PyIMEngineFactoryType);	
}
